#pragma once
#include "stdafx.h"

template<typename T>class MyUniquePTR
{
	T* ptr {};

public:
	MyUniquePTR() = default;
	MyUniquePTR(T* addr) noexcept;
	MyUniquePTR(const MyUniquePTR&) = delete;
	MyUniquePTR(MyUniquePTR&& other) noexcept;
	constexpr MyUniquePTR(nullptr_t) noexcept : ptr() {};
	MyUniquePTR<T>& operator=(const MyUniquePTR&) = delete;
	//MyUniquePTR<T>& operator=(MyUniquePTR&&) noexcept;

	T* operator->() noexcept;
	T& operator*() noexcept;
	const T* operator->() const noexcept;
	const T& operator*() const noexcept;
	explicit operator bool() const noexcept;

	~MyUniquePTR() noexcept;
};

template<typename T>
inline MyUniquePTR<T>::MyUniquePTR(T* addr) noexcept
	:ptr(addr) {}

template<typename T>
inline MyUniquePTR<T>::MyUniquePTR(MyUniquePTR&& other) noexcept
	:ptr(other.ptr) 
{
	other.ptr = nullptr;
}

//template<typename T>
//inline MyUniquePTR<T>& MyUniquePTR<T>::operator=(MyUniquePTR&& other) noexcept
//{
//	ptr = other.ptr;
//	other.ptr = nullptr;
//	return *this;
//}

template<typename T>
inline T* MyUniquePTR<T>::operator->() noexcept
{
	return ptr;
}

template<typename T>
inline T& MyUniquePTR<T>::operator*() noexcept
{
	return *ptr;
}

template<typename T>
inline const T* MyUniquePTR<T>::operator->() const noexcept
{
	return ptr;
}

template<typename T>
inline const T& MyUniquePTR<T>::operator*() const noexcept
{
	return *ptr;
}

template<typename T>
inline MyUniquePTR<T>::operator bool() const noexcept
{
	return ptr;
}

template<typename T>
inline MyUniquePTR<T>::~MyUniquePTR() noexcept
{
	if (ptr) { delete ptr; }
}
